package generation;

import java.util.ArrayList;

/**
 * @author Boshi Li
 */
public class CodeTable {
	ArrayList< CodeTableElement > codeTable = new ArrayList< CodeTableElement >();
	
	private int index = 0;
	
	/**
	 * optimize then add three address codes to table 
	 * @param operator
	 * @param address1
	 * @param address2
	 * @param result
	 * @return if it eliminate temporary 
	 */
	public boolean add( String operator, String address1, String address2 , String result ){
		if( operator.equals("asg") && 
			codeTable.size()>0 &&
			isExpOperator(  get( codeTable.size()-1 ).getOperator() ) && 
			address1.equals(  get( codeTable.size()-1 ).getResult() ) &&
			get( codeTable.size()-1 ).getResult().contains("t")){
			//to do something like this
//			//(add, t1 , t2 , t3)
//			//(asg , t3 , - , b)
//			//		   =>
//			//(add t1 , t2 , b)
			get( codeTable.size()-1 ).setResult( result );
			return true;
		}else if( operator.equals("lab")){
			String lastOpr = get( codeTable.size()-1 ).getOperator();
			if( ( lastOpr.equals("iff") || lastOpr.equals("ift")|| lastOpr.equals("goto") ) &&  get( codeTable.size()-1 ).getResult().equals( result )){
				codeTable.remove( codeTable.size()-1 );
			}
			codeTable.add( new CodeTableElement( -1 , operator, address1, address2, result));
		}else{
			codeTable.add( new CodeTableElement( index , operator, address1, address2, result));
			index++;
		}	
		return false;
	}

	/**
	 * @return size of code table
	 */
	public int size() {
		return codeTable.size();
	}
	
	/**
	 * pop last element of code table
	 */
	public void pop(){
		codeTable.remove( codeTable.size()-1 );
	}

	/**
	 * return i element of code table
	 * @param i
	 * @return
	 */
	public CodeTableElement get(int i) {
		return codeTable.get(i);
	}
	
	/**
	 * return number that label represented
	 * @param labLineNum
	 * @return
	 */
	public int getLabResprentNum( int labLineNum ){
		int index = -1;
		while( index == -1 ){
			labLineNum++;
			
			if( labLineNum>=codeTable.size() ){
				//represent there is no statement below last lab
				//it only happens it must be returned before function ends
				return -1;
			}
			index = codeTable.get( labLineNum ).getIndex();
		}
		return index;
	}
	
	/**
	 * judge if operator is expression operator
	 * @param operator
	 * @return
	 */
	private boolean isExpOperator( String operator ){
		return operator.equals("uminus") 
				|| operator.equals("not") 
				|| operator.equals("lte") 
				|| operator.equals("lt")
				|| operator.equals("gt") 
				|| operator.equals("gte") 
				|| operator.equals("eq")
				|| operator.equals("neq") 
				|| operator.equals("add") 
				|| operator.equals("sub")
				|| operator.equals("or") 
				|| operator.equals("mul") 
				|| operator.equals("div")
				|| operator.equals("mod") 
				|| operator.equals("and")
				|| operator.equals("rdi")
				|| operator.equals("rdb");
	}
}
